Skip to content

fix(web): add Safari fallback for requestIdleCallback#9137

Merged
sriramveeraghanta merged 2 commits into
makeplane:previewfrom
KanteshMurade:fix-safari-requestidlecallback-clean
May 28, 2026
Merged

fix(web): add Safari fallback for requestIdleCallback#9137
sriramveeraghanta merged 2 commits into
makeplane:previewfrom
KanteshMurade:fix-safari-requestidlecallback-clean

Conversation

@KanteshMurade
Copy link
Copy Markdown
Contributor

@KanteshMurade KanteshMurade commented May 25, 2026

Description

Fixes a Safari/iOS crash caused by unguarded usage of window.requestIdleCallback in the project layout/gantt view.

Safari does not currently support requestIdleCallback by default, which caused the following runtime error:

TypeError: window.requestIdleCallback is not a function

This PR adds a shared compatibility fallback for:

  • requestIdleCallback
  • cancelIdleCallback

The polyfill is installed during client startup before React hydration, while preserving native behavior in Chrome and Firefox.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

N/A

Test Scenarios

  • Ran web lint checks successfully
  • Verified Safari fallback executes when requestIdleCallback is unavailable
  • Confirmed no unsafe direct usages remain outside shared compatibility layer

References

Closes #9134

Summary by CodeRabbit

  • Chores
    • Improved browser compatibility for idle-task scheduling with robust fallbacks so background work runs reliably across browsers and environments.
    • Centralized and simplified startup initialization of compatibility features to make app startup more consistent and maintainable.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 35c009a7-4d48-4d59-a0d8-7b4a462f7e9b

📥 Commits

Reviewing files that changed from the base of the PR and between b6e7368 and 201f849.

📒 Files selected for processing (1)
  • apps/web/core/lib/idle-task.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/core/lib/idle-task.ts

📝 Walkthrough

Walkthrough

The PR centralizes idle-callback handling with requestIdle/cancelIdle wrappers, installs those wrappers into globalThis during module initialization, and imports the polyfills module in the client entry before React hydration.

Changes

Safari requestIdleCallback Polyfill Setup

Layer / File(s) Summary
Idle callback abstraction and runIdleTask update
apps/web/core/lib/idle-task.ts
Adds setTimeout-based fallback helpers, exports requestIdle/cancelIdle wrappers that prefer native globalThis APIs, provides installIdleCallbackPolyfill(), and updates runIdleTask to accept IdleRequestCallback and schedule via requestIdle(..., { timeout: 300 }).
Polyfill module initialization
apps/web/core/lib/polyfills/index.ts
Imports installIdleCallbackPolyfill, invokes it during module load to install requestIdleCallback/cancelIdleCallback when absent, and exports default true.
Client entry integration
apps/web/app/entry.client.tsx
Imports and executes the polyfills module for side effects (void polyfills) before starting React hydration to ensure the polyfill is available globally.

Sequence Diagram(s)

sequenceDiagram
  participant Client as entry.client
  participant Polyfills as polyfills/index
  participant IdleTask as idle-task.installIdleCallbackPolyfill
  participant Global as globalThis
  participant Runtime as runtime (task scheduling)
  Client->>Polyfills: import & execute (void polyfills)
  Polyfills->>IdleTask: installIdleCallbackPolyfill()
  IdleTask->>Global: set requestIdleCallback / cancelIdleCallback (native or fallback)
  Client->>IdleTask: runIdleTask(callback) -> requestIdle(callback, {timeout:300})
  IdleTask->>Runtime: schedule via globalThis.requestIdleCallback or setTimeout
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Possibly related PRs

  • makeplane/plane#9094: Modifies the shared idle-callback plumbing (apps/web/core/lib/idle-task.ts) and the runIdleTask API similar to this PR.

Suggested reviewers

  • sriramveeraghanta
  • codingwolf-at

Poem

🐰 I nibble code in morning light,

Polyfills hop in, make Safari right.
Idle tasks now find their bed,
No more crashes — peace ahead.
🥕✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a Safari fallback for requestIdleCallback to fix a browser compatibility issue.
Description check ✅ Passed The PR description covers all required template sections including a detailed description, type of change selection, test scenarios, and references the related issue #9134.
Linked Issues check ✅ Passed The code changes fully address issue #9134 by implementing a global requestIdleCallback/cancelIdleCallback polyfill that prevents TypeError crashes in Safari while preserving native behavior in supporting browsers [#9134].
Out of Scope Changes check ✅ Passed All changes are within scope: idle-task.ts was refactored to support the polyfill fallback, polyfills/index.ts delegates to the new centralized implementation, and entry.client.tsx invokes the polyfill during startup—all directly related to resolving issue #9134.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/core/lib/idle-task.ts`:
- Around line 11-37: The fallback implementations and availability checks should
use globalThis instead of window to avoid runtime errors when window is
undefined: update requestIdleFallback and cancelIdleFallback to call
globalThis.setTimeout and globalThis.clearTimeout, and change the runtime checks
in requestIdle and cancelIdle to use typeof globalThis !== "undefined" and
typeof globalThis.requestIdleCallback / globalThis.cancelIdleCallback ===
"function" so you only call globalThis.requestIdleCallback(globalCallback,
options) when available and otherwise return requestIdleFallback(callback) /
cancelIdleFallback(id).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2707e4a8-912b-4ba0-864a-2c084b23bf1d

📥 Commits

Reviewing files that changed from the base of the PR and between e71a8f5 and b6e7368.

📒 Files selected for processing (3)
  • apps/web/app/entry.client.tsx
  • apps/web/core/lib/idle-task.ts
  • apps/web/core/lib/polyfills/index.ts

Comment thread apps/web/core/lib/idle-task.ts Outdated
Switch idle-task fallback paths from window.* to globalThis.* so the
fallback no longer crashes in environments where window is undefined.
Also thread IdleRequestOptions through requestIdleFallback so the
caller's timeout hint is honored when falling back.

Addresses CodeRabbit review feedback on makeplane#9137.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

Actionable comments posted: 0

@sriramveeraghanta sriramveeraghanta merged commit f14451a into makeplane:preview May 28, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: Opening a project crashes in Safari/iOS — window.requestIdleCallback is not a function (gantt-layout-loader, unguarded)

2 participants